/*
 * Created by Spear (http://www.codernet.es), spear@codernet.es
 * Coordinator of XNA Community (http://www.codeplex.com/XNACommunity)
 * 
 */
/*
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace SkeletonBaseLibrary
{
  public class CSkeletonBase
  {
    Model model = null;
    CSkeletonData skeleton_data;
    CSkeletonData.CAnimationData current_animation;
    string current_animation_name;
    Matrix[] bones;
    Matrix[] absolute_bones;
    int prev_frame_id;

    float time = 0.0f;
    float scale_time = 1.0f;

    //Skeleton Lines, to render, debug...
    List<Vector3> skeleton_lines = new List<Vector3>();

    public CSkeletonBase(Model m)
    {
      model = m;
      prev_frame_id = 0;
      skeleton_data = model.Tag as CSkeletonData;
      if (skeleton_data == null)
        throw new InvalidOperationException
            ("This model does not contain a CSkeletonData tag.");
      else {
        if (skeleton_data.list_animations.Count > 0) 
        {
          Dictionary<string, CSkeletonData.CAnimationData>.Enumerator e = skeleton_data.list_animations.GetEnumerator();
          if (e.MoveNext())
          {
            CSkeletonData.CAnimationData anim = e.Current.Value;
            int num_bones = anim.list_frames[0].list_skeleton.Count;
            bones = new Matrix[num_bones];
            absolute_bones = new Matrix[num_bones];
            current_animation = anim;
            current_animation_name = e.Current.Key;
          }
        }
      }
    }

    public void setAnimation(string name)
    {
      if (name == current_animation_name)
        return;

      if (skeleton_data.list_animations.ContainsKey(name))
      {
        current_animation = skeleton_data.list_animations[name];
        current_animation_name = name;
        prev_frame_id = 0;
      }
      else
      {
        throw new InvalidOperationException
            ("This model hasn't animation '" + name + "'.");
      }
    }

    public List<Vector3> getSkeletonLines()
    {
      return skeleton_lines;
    }

    private void clearSkeletonLines()
    {
      skeleton_lines.Clear();
    }

    private void addSkeletonLine(Vector3 v1, Vector3 v2)
    {
      skeleton_lines.Add(v1);
      skeleton_lines.Add(v2);
    }

    public void calculateBoneTransforms(CSkeletonData.CFramesData p_frame, CSkeletonData.CFramesData c_frame, float amount)
    {
      //Matrix[] world_transform = new Matrix[bones.Length];
      for (int i = 0; i < c_frame.list_skeleton.Count; ++i)
      {
        Quaternion oriented = Quaternion.Slerp(p_frame.list_skeleton[i].oriented, c_frame.list_skeleton[i].oriented, amount);
        oriented.Normalize();
        Vector3 pos = Vector3.Lerp(p_frame.list_skeleton[i].pos,c_frame.list_skeleton[i].pos, amount);

        Matrix bone_local_transform = Matrix.CreateFromQuaternion(oriented) * Matrix.CreateTranslation(pos);
        int parent_id = c_frame.list_skeleton[i].parent;
        if (parent_id >= 0)
        {
          absolute_bones[i] = bone_local_transform * absolute_bones[parent_id];
        }
        else
        {
          absolute_bones[i] = bone_local_transform;
        }
      }

      for (int i = 0; i < bones.Length; ++i)
      {
        bones[i] = skeleton_data.bind_skeleton[i] * absolute_bones[i];
      }

      //calculate lines
      clearSkeletonLines();
      for (int i = 0; i < absolute_bones.Length; ++i)
      {
        int parent_id = c_frame.list_skeleton[i].parent;
        if (parent_id >= 0)
        {
          Vector3 v1 = absolute_bones[parent_id].Translation;
          Vector3 v2 = absolute_bones[i].Translation;
          addSkeletonLine(v1, v2);
        }
      }
    }


    public void update(GameTime game_time) 
    {
      float elapsed = (game_time.ElapsedGameTime.Milliseconds / 1000.0f) * scale_time;
      //Mixer update
      time += elapsed;
      float t = time / current_animation.frame_rate;
      int nframes = (int) t;
      if (nframes == 0)
        return;
      time -= (current_animation.frame_rate * nframes); //time rest
      prev_frame_id += nframes;
      if (prev_frame_id >= current_animation.list_frames.Count)
      {
        int f = prev_frame_id / current_animation.list_frames.Count;
        prev_frame_id -= current_animation.list_frames.Count * f;
      }
      int current_frame_id = prev_frame_id + 1;
      if (current_frame_id >= current_animation.list_frames.Count)
      {
        current_frame_id -= current_animation.list_frames.Count;
      }
      CSkeletonData.CFramesData current_frame = current_animation.list_frames[current_frame_id];
      CSkeletonData.CFramesData prev_frame = current_animation.list_frames[prev_frame_id];
      calculateBoneTransforms(prev_frame, current_frame, time);
    }

    public Matrix[] getSkinTransforms(int mesh_id)
    {
      return bones;
    }

    public Matrix[] getAbsoluteBonesTransforms(int mesh_id)
    {
      return absolute_bones;
    }

    public float TimeScale
    {
      get { return scale_time; }
      set { scale_time = value; }
    }

  }
}
*/